import {
	window,
	commands,
	workspace,
	QuickPick,
	QuickPickItem,
	ExtensionContext,
	StatusBarAlignment,
} from 'vscode';

import * as fs from 'fs';
import * as path from 'path';

import bookStream from './bookStream';

interface QuickPickItemAction extends QuickPickItem {
	action: Action;
}

interface Action {
    (item: QuickPickItemAction): void;
}

interface Book {
	fileName: string;
	size: number;
	bytesRead: number;
}

async function getBookList(bookPath: string, historyDirPath: string): Promise<Book[]> {
	const fileList: string[] = await new Promise((resolve) => {
		fs.readdir(bookPath, { withFileTypes: true }, (err, list) => {
			if (err) {
				window.showErrorMessage(JSON.stringify(err));
				list = [];
			}
			const resultList = list.filter((item) => item.isFile()).map((item) => {
				return item.name;
			});
			resolve(resultList);
		});
	});
	const bookList = [];
	for (const fileName of fileList) {
		const historyPath = path.resolve(historyDirPath, `${ path.basename(fileName) }.history`);
		try {
			const history = JSON.parse(fs.readFileSync(historyPath).toString());
			history.fileName = fileName;
			bookList.push(history);
		} catch (error) {
			bookList.push({ fileName });
		}
	}
	return bookList;
}

function setBookList(bookList: Book[], action: Action, quickPick: QuickPick<QuickPickItemAction>) {
	const itemList: QuickPickItemAction[] = [];
	for (const book of bookList) {
		itemList.push({
			action,
			label: book.fileName,
			description: book.size > 0 ? `${ (book.bytesRead / book.size).toFixed(2) }%` : '0.00%', 
		});
	}
	quickPick.value = '';
	quickPick.busy = false;
	quickPick.items = itemList;
	quickPick.placeholder = '选择要阅读的书籍';
	quickPick.show();
}

interface Result {
	value: string;
	percentage: string;
}

interface Handle {
	last(): Promise<Result>;
	next(): Promise<Result>;
	stop(): void;
	skip(index: number): Promise<Result>;
}

export function activate(context: ExtensionContext) {
	let readLock = false;

	const quickPick: QuickPick<QuickPickItemAction> = window.createQuickPick();
	quickPick.busy = false;
    quickPick.matchOnDetail = true;
	quickPick.canSelectMany = false;
	quickPick.matchOnDescription = true;
	quickPick.onDidAccept(async () => {
		const item = quickPick.selectedItems[0];
		if (!quickPick.busy && item.action) {
			quickPick.busy = true;
			await item.action(item);
		}
	});

	const view = window.createStatusBarItem(StatusBarAlignment.Left);
	view.hide();

	const last = window.createStatusBarItem(StatusBarAlignment.Right);
	last.text = '◀';
	last.tooltip = '上一页';
	last.command = 'readBook.last';
	last.show();

	const stop = window.createStatusBarItem(StatusBarAlignment.Right);
	stop.text = '■';
	stop.tooltip = '停止';
	stop.command = 'readBook.stop';
	stop.show();

	const next = window.createStatusBarItem(StatusBarAlignment.Right);
	next.text = '▶';
	next.tooltip = '下一页';
	next.command = 'readBook.next';
	next.show();

	const percentage = window.createStatusBarItem(StatusBarAlignment.Right);
	percentage.text = '';
	percentage.tooltip = '跳转';
	percentage.command = 'readBook.skip';
	percentage.show();

	// 文件操作句柄
	let handle: Handle;

	context.subscriptions.push(commands.registerCommand('readBook.start', async () => {
		if (readLock) {
			return;
		}
		let bookPath: string = workspace.getConfiguration('readBook').get('path') || '';
		if (!bookPath) {
			window.showInformationMessage('尚未配置书籍文件夹路径！');
			bookPath = await window.showInputBox({ placeHolder: '填写书籍文件夹路径' }) || '';
			if (!bookPath) {
				return;
			}
			await workspace.getConfiguration('readBook').update('path', bookPath);
		}
		bookPath = path.resolve(bookPath);
		let historyPath: string = workspace.getConfiguration('readBook').get('history') || '';
		if (!historyPath) {
			window.showInformationMessage('尚未配置阅读历史记录文件路径！');
			historyPath = await window.showInputBox({ placeHolder: '填写书籍阅读历史记录文件路径' }) || '';
			if (!historyPath) {
				return;
			}
			await workspace.getConfiguration('readBook').update('history', historyPath);
		}
		historyPath = path.resolve(historyPath);
		// 获取文件列表
		const bookList = await getBookList(bookPath, historyPath);
		setBookList(bookList, async (item: QuickPickItemAction) => {
			const filePath = path.resolve(bookPath, item.label);
			const limit: number = workspace.getConfiguration('readBook').get('limit') || 50;
			handle = await bookStream(filePath, limit, historyPath);
			const result = await handle.next();
			view.text = result.value;
			percentage.text = result.percentage;
			quickPick.hide();
			readLock = true;
			view.show();
			next.show();
			stop.show();
			last.show();
			percentage.show();
		}, quickPick);
	}));

	context.subscriptions.push(commands.registerCommand('readBook.stop', () => {
		if (!readLock) {
			return;
		}
		handle.stop();
		readLock = false;
		view.hide();
		next.hide();
		stop.hide();
		last.hide();
		percentage.hide();
	}));

	context.subscriptions.push(commands.registerCommand('readBook.next', async () => {
		if (readLock && view.text !== '') {
			const result = await handle.next();
			view.text = result.value;
			percentage.text = result.percentage;
		}
	}));

	context.subscriptions.push(commands.registerCommand('readBook.last', async () => {
		if (readLock) {
			const result = await handle.last();
			view.text = result.value;
			percentage.text = result.percentage;
		}
	}));

	context.subscriptions.push(commands.registerCommand('readBook.skip', async () => {
		if (readLock) {
			const value = await window.showInputBox({ placeHolder: '请输入跳转百分比' }) || '';
			if (!value) {
				return;
			}
			const result = await handle.skip(Number(value) / 100);
			view.text = result.value;
			percentage.text = result.percentage;
		}
	}));
}

export function deactivate() {}
